﻿using HalconDotNet;
using Halcon二次开发.Controller.Controller基类;
using Halcon二次开发.Model.储存每个Controller的单例对象;
using Halcon二次开发.Model.工具区域的扩展类;
using Halcon二次开发.Model;
using Halcon二次开发.View.找圆_线_矩形;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Halcon二次开发.Model.储放所有单例.储存每个单例界面;
using System.Windows.Forms;
using System.Windows.Media.Media3D;
using NumericUpDown = System.Windows.Forms.NumericUpDown;
using Halcon二次开发.Tools;
using System.Windows;
using Halcon二次开发.Model.自定义控件;

namespace Halcon二次开发.Controller.画线工具交互
{
    public class FindCrileToolController
    {
        int index = 0;
        HTuple hv_line_ = new HTuple();
        /// <summary>
        /// 所有线段的对象
        /// </summary>
        HDrawingObjectEx line;
        /// <summary>
        /// 当前控件对象
        /// </summary>
        HSmartWindowControl hw;

        /// 移动事件更改数据禁止
        /// </summary>
        bool check = false;
        /// <summary>
        /// 界面
        /// </summary>
        H_FindCirleToolForm form;
        /// <summary>
        /// 卡尺的位置半径
        /// </summary>
        NumericUpDown numericUpDown1, numericUpDown2, numericUpDown3;
        /// <summary>
        ///当前工位
        /// </summary>
        HwindowFlowNodeUrseControl hwindowFlowNode;

        #region 输入输出参数
        /// <summary>
        /// 当前输入对象
        /// </summary>
        public HObject HideIntputImage;
        /// <summary>
        /// 卡尺的位置   
        /// </summary>
        public double HideIntputX, HideIntputY, HideIntputRadius, HideOutputCenterX, HideOutputCenterY, HideOutputRadius;
        /// <summary>
        /// 卡尺的宽度,高度,对比度,平滑度
        /// </summary>
        public double HideIntputWidth = 0, HideIntputHeight = 0, HideIntputThreshold, HideIntputSigma;
        /// <summary>
        /// 颜色样式
        /// </summary>
        string HideOutputBorderColor, HideOutputCenterConlor, HideOutputlineColor = "green";
        /// <summary>
        /// 抓边成功
        /// </summary>
        bool OK = false;
        /// <summary>
        /// 卡尺数量
        /// </summary>
        public int CaliperNumber = 10;
        /// <summary>
        /// 输入的行-列-角度坐标
        /// </summary>
        public double[] HideIntputArrayRows, HideIntputArrayColumns, HideIntputArrayPhis;
        /// <summary>
        /// 输出参数
        /// 输出x坐标，输出y坐标，输出圆的半径
        /// </summary>
        public double[] HideOutputArrayRows, HideOutputArrayColumns, HideOutputArrayDistances;
        public FindCrileToolController(H_FindCirleToolForm form,HwindowFlowNodeUrseControl hwindowFlowNode) {
            //获取当前工位
            this.hwindowFlowNode = hwindowFlowNode; 
            hw = hwindowFlowNode.hSmartWindowControl1;
            this.form = form;
        }
        #endregion
        /// <summary>
        /// 画圆按钮触发方法
        /// </summary>

        public void DrawCrile(NumericUpDown numericUpDown1, NumericUpDown numericUpDown2, NumericUpDown numericUpDown3, NumericUpDown numericUpDown4,
            NumericUpDown numericUpDown8, NumericUpDown numericUpDown9, NumericUpDown numericUpDown6, NumericUpDown numericUpDown5, TextBox textBox1, TextBox textBox2,
            TextBox textBox3 ){
            HideOutputlineColor = textBox3.Text;
            
            if (HideIntputImage == null)
            {
                throw new Exception("当前图像为空");
            }

            //标志红心
            if (HideIntputArrayRows != null && HideIntputArrayRows.Length > 0)
            {
                HOperatorSet.SetColor(hw.HalconWindow, "red");
                HOperatorSet.SetDraw(hw.HalconWindow, "fill");
                HOperatorSet.GenCircle(out HObject ho_Biaozhu, HideIntputArrayRows[0], HideIntputArrayColumns[0], 20);
                HOperatorSet.DispObj(ho_Biaozhu, hw.HalconWindow);
                HOperatorSet.SetColor(hw.HalconWindow, HideOutputlineColor.ToLower());
                HOperatorSet.SetDraw(hw.HalconWindow, "margin");
            }

            //抓边成功就不用执行了
            if (OK) return;
            OK = true;
            ClearObject();
            //定义绘制线的开始坐标与结束坐标 行坐标,列坐标,半径
            var lineTuple = new HTuple[] { 100, 100, 50 };
            //创建圆的对象
            var lineObj = HDrawingObject.CreateDrawingObject(HDrawingObject.HDrawingObjectType.CIRCLE, lineTuple);

            //设置线的颜色
            try
            {
                lineObj.SetDrawingObjectParams("color", HideOutputlineColor.ToLower());
            }
            catch
            {
                lineObj.SetDrawingObjectParams("color", "red");
                throw new Exception("该线条不支持此颜色以为你选择默认颜色!");
            }

            //圆拖动触发事件注册
            lineObj.OnDrag(LineOnDrag);
            //圆长度修改触发事件注册
            lineObj.OnResize(LineOnResize);
            //永久保留该对象,不然会被垃圾回收机制回收
            line = (new HDrawingObjectEx
            {
                HDrawingObject = lineObj,
                hTuples = lineTuple
            });
            //增加这个对象到指定Halcon窗口
            hw.HalconWindow.AttachDrawingObjectToWindow(lineObj);

            HideIntputX = double.Parse(numericUpDown1.Value+"");
            HideIntputY = double.Parse(numericUpDown2.Value+"");
            HideIntputRadius = double.Parse(numericUpDown3.Value+"");

            this.numericUpDown1 = numericUpDown1;
            this.numericUpDown2 = numericUpDown2;
            this.numericUpDown3 = numericUpDown3;

            this.HideIntputThreshold = double.Parse(numericUpDown8.Value + "");
            this.HideIntputSigma = double.Parse(numericUpDown9.Value + "");
            this.HideIntputHeight = double.Parse(numericUpDown5.Value + "");
            this.HideIntputWidth = double.Parse(numericUpDown6.Value + "");
            this.HideOutputBorderColor = textBox1.Text;
            this.HideOutputCenterConlor = textBox2.Text;
            this.HideOutputlineColor = textBox3.Text;
            paper = true;
        }

        private void LineOnResize(HDrawingObject drawid, HWindow window, string type)
        {
            UpdataDrawingObjecData(drawid);
        }

        private void LineOnDrag(HDrawingObject drawid, HWindow window, string type)
        {
            UpdataDrawingObjecData(drawid);
        }

        public void UpdataDrawingObjecData(HDrawingObject drawid)
        {
            
            //创建一个要得到对象属性的元组
            var attTuple = new HTuple("row", "column", "radius");
            //获取对应的属性
            var valueTuple = drawid.GetDrawingObjectParams(attTuple);
            //对对应的属性进行封装一下,后面好加入到集合中
            var attValues = new HTuple[] { valueTuple[0], valueTuple[1], valueTuple[2] };
            HideIntputX = valueTuple[1];
            HideIntputY = valueTuple[0];
            HideIntputRadius = valueTuple[2];
            //更新数据
            line.hTuples = attValues;
            this.numericUpDown1.Value = decimal.Parse(valueTuple[1].D.ToString());
            this.numericUpDown2.Value = decimal.Parse(valueTuple[0].D.ToString());
            this.numericUpDown3.Value = decimal.Parse(valueTuple[2].D.ToString());
            Debug.WriteLine(valueTuple[0].D + " " + valueTuple[1].D + " " + valueTuple[2].D);
        }

        /// <summary>
        /// 开始抓边
        /// </summary>
        //基准数据，第一次的数据
        private double JiRow, JiCol, JiPhi;
        //记录第一次变量标志位
        public bool paper = true;
        public void Bound_Line()
        {
            ClearObject();
            if (HideIntputImage == null)
            {
                throw new Exception("当前图像为空");
            }
            try
            {

                if (HideIntputArrayRows != null && HideIntputArrayRows.Length > 0)
                {
                    //i等于0的时候计算我们基准数据
                    if (paper)
                    {
                        if (HideIntputArrayRows != null && HideIntputArrayRows.Length > 0)
                        {
                            JiRow = HideIntputArrayRows[0];
                            JiCol = HideIntputArrayColumns[0];
                            JiPhi = HideIntputArrayPhis[0];
                            paper = false;
                        }

                    }
                    if (HideIntputArrayRows != null && HideIntputArrayRows.Length > 0)
                    {
                        HideOutputArrayRows = new double[HideIntputArrayRows.Length];
                        HideOutputArrayColumns = new double[HideIntputArrayColumns.Length];
                        HideOutputArrayDistances = new double[HideIntputArrayPhis.Length];
                        //创建测量的计量模型
                        HOperatorSet.CreateMetrologyModel(out HTuple hv_MetrologyHandle);

                        form.dataGridView1.Rows.Clear();
                        index = 0;
                        for (int i = 0; i < HideIntputArrayRows.Length; i++)
                        {
                            double raids = (double)form.numericUpDown3.Value;
                            HOperatorSet.GenCircle(out HObject fs, JiRow, JiCol, raids);
                            HObject hobj = UtiyHalcon.MatrixCalculate(fs, HideIntputArrayRows[i], HideIntputArrayColumns[i], raids, JiRow, JiCol, raids);

                            HOperatorSet.SmallestCircle(hobj, out HTuple rowsss, out HTuple Columnsss, out HTuple radiusss);
                            HOperatorSet.SetDraw(hw.HalconWindow, "margin");
                            HOperatorSet.SetColor(hw.HalconWindow, "red");
                            HOperatorSet.DispObj(hobj, hw.HalconWindow);
                            //将计量模型添加到计算计量模型中
                            HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, rowsss, Columnsss, radiusss,
                            double.Parse(form.numericUpDown5.Value.ToString()), double.Parse(form.numericUpDown6.Value.ToString()), HideIntputSigma, HideIntputThreshold, new HTuple(), new HTuple(), out HTuple hv_Index);
                            //该参数指定暗/亮或亮/暗边的使用  negative:正极性  positive:负极性  uniform:正负极性只有一个
                            //获取极性
                            string polarity = "";
                            if (form.comboBox1.SelectedItem.ToString() == "全部")
                            {
                                polarity = "all";
                            }
                            if (form.comboBox1.SelectedItem.ToString() == "正极性")
                            {
                                polarity = "negative";
                            }
                            if (form.comboBox1.SelectedItem.ToString() == "负极性")
                            {
                                polarity = "positive";
                            }
                            if (form.comboBox1.SelectedItem.ToString() == "仅有")
                            {
                                polarity = "uniform";
                            }
                            //设置极性
                            HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, "all", "measure_transition", polarity);
                            //卡尺数量
                            HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, "all", "num_measures", int.Parse(form.numericUpDown4.Value.ToString()));
                            //卡尺卡的数量 接受的结果数
                            HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, "all", "num_instances", int.Parse(form.numericUpDown11.Value.ToString()));

                            HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, "all", "measure_interpolation", "bicubic");
                            HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, "all", "measure_select", "all");
                            HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, "all", "min_score", double.Parse(form.numericUpDown10.Value.ToString()));

                            //开始抓
                            HOperatorSet.ApplyMetrologyModel(HideIntputImage, hv_MetrologyHandle);
                            HOperatorSet.GetMetrologyObjectMeasures(out HObject ho_Contours, hv_MetrologyHandle, "all", "all",
                                out HTuple hv_Row, out HTuple hv_Column);

                            if (hv_Row.Length > 0 && hv_Column.Length > 0)
                            {

                                //得到距离在hv_Parameter中
                                HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, 0, "all", "result_type", "all_param",
                                    out HTuple hv_Parameter);
                                //没抓到
                                if (hv_Parameter.Length > 0)
                                {
                                    HideOutputArrayRows[i] = rowsss;
                                    HideOutputArrayColumns[i] = Columnsss;
                                    HideOutputArrayDistances[i] = radiusss;
                                    //设置边框颜色
                                    HOperatorSet.SetColor(hw.HalconWindow, form.textBox2.Text.ToLower());

                                    HOperatorSet.DispObj(ho_Contours, hw.HalconWindow);

                                    HOperatorSet.GetMetrologyObjectResultContour(out HObject ho_Contour, hv_MetrologyHandle, 0, "all", 1.5);
                                    //中心线颜色
                                    HOperatorSet.SetColor(hw.HalconWindow, form.textBox1.Text.ToLower());

                                    HOperatorSet.SetLineWidth(hw.HalconWindow, 3);
                                    HOperatorSet.DispObj(ho_Contour, hw.HalconWindow);
                                    //添加结果集
                                    HideOutputCenterX = Columnsss;
                                    HideOutputCenterY = rowsss;
                                    HideOutputRadius = radiusss;
                                    form.dataGridView1.Rows.Add(index, Columnsss, rowsss, radiusss);
                                    index++;
                                }
                                else
                                {
                                    throw new Exception("找圆工具未找到!");
                                }
                            }
                            else
                            {
                                throw new Exception("找圆工具未找到!");
                            }
                        }
                    }
                }
                else
                {
                    HOperatorSet.CreateMetrologyModel(out HTuple hv_MetrologyHandle);
                    HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, HideIntputY, HideIntputX, HideIntputRadius,
                         double.Parse(form.numericUpDown5.Value.ToString()), double.Parse(form.numericUpDown6.Value.ToString()), HideIntputSigma, HideIntputThreshold, new HTuple(), new HTuple(), out HTuple hv_Index);
                    //该参数指定暗/亮或亮/暗边的使用  negative:正极性  positive:负极性  uniform:正负极性只有一个
                    //获取极性
                    string polarity = "";
                    if (form.comboBox1.SelectedItem.ToString() == "全部")
                    {
                        polarity = "all";
                    }
                    if (form.comboBox1.SelectedItem.ToString() == "正极性")
                    {
                        polarity = "negative";
                    }
                    if (form.comboBox1.SelectedItem.ToString() == "负极性")
                    {
                        polarity = "positive";
                    }
                    if (form.comboBox1.SelectedItem.ToString() == "仅有")
                    {
                        polarity = "uniform";
                    }
                    form.dataGridView1.Rows.Clear();
                    //设置极性
                    HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, "all", "measure_transition", polarity);
                    //卡尺数量
                    HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, "all", "num_measures", int.Parse(form.numericUpDown4.Value.ToString()));
                    //卡尺卡的数量 接受的结果数
                    HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, "all", "num_instances", int.Parse(form.numericUpDown11.Value.ToString()));

                    HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, "all", "measure_interpolation", "bicubic");
                    HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, "all", "measure_select", "all");
                    HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, "all", "min_score", double.Parse(form.numericUpDown10.Value.ToString()));

                    //开始抓
                    HOperatorSet.ApplyMetrologyModel(HideIntputImage, hv_MetrologyHandle);
                    HOperatorSet.GetMetrologyObjectMeasures(out HObject ho_Contours, hv_MetrologyHandle, "all", "all",
                        out HTuple hv_Row, out HTuple hv_Column);

                    if (hv_Row.Length > 0 && hv_Column.Length > 0)
                    {

                        //得到距离在hv_Parameter中
                        HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, 0, "all", "result_type", "all_param",
                            out HTuple hv_Parameter);
                        //没抓到
                        if (hv_Parameter.Length > 0)
                        {
                            //设置边框颜色
                            HOperatorSet.SetColor(hw.HalconWindow, form.textBox2.Text.ToLower());

                            HOperatorSet.DispObj(ho_Contours, hw.HalconWindow);

                            HOperatorSet.GetMetrologyObjectResultContour(out HObject ho_Contour, hv_MetrologyHandle, 0, "all", 1.5);
                            //中心线颜色
                            HOperatorSet.SetColor(hw.HalconWindow, form.textBox1.Text.ToLower());

                            HOperatorSet.SetLineWidth(hw.HalconWindow, 3);
                            HOperatorSet.DispObj(ho_Contour, hw.HalconWindow);
                            //添加结果集
                            HideOutputCenterX = hv_Parameter[1].D;
                            HideOutputCenterY = hv_Parameter[0].D;
                            HideOutputRadius = hv_Parameter[2].D;
                            form.dataGridView1.Rows.Add(index, hv_Parameter[1].D, hv_Parameter[0].D, hv_Parameter[2].D);
                        }
                        else
                        {
                            throw new Exception("找圆工具未找到!");
                        }
                    }
                    else
                    {
                        throw new Exception("找圆工具未找到!");
                    }
                }

            }
            catch(Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 清除这个线对象
        /// </summary>
        public void ClearObject()
        {
            if (line == null) return;
            var hobject = line.HDrawingObject;
            if (hobject.ID == 0) return;
            hw.HalconWindow.DetachDrawingObjectFromWindow(hobject);
            OK = false;
            //hobject.Dispose();
        }

        /// <summary>
        /// shuzhi移动
        /// </summary>
        public void Move_X(double x1, double y1, double raduis)
        {
            //if (check)
            //{
            //    return;
            //}
            //ClearObject();
            //HideIntputX = x1;
            //HideIntputY = y1;
            //HideIntputRadius = raduis;
            ////定义绘制线的开始坐标与结束坐标
            //var lineTuple = new HTuple[] { y1, x1, raduis };
            ////创建线的对象
            //var lineObj = HDrawingObject.CreateDrawingObject(HDrawingObject.HDrawingObjectType.CIRCLE, lineTuple);
            ////线段拖动触发事件注册
            //lineObj.OnDrag(LineOnDrag);
            ////线段长度修改触发事件注册
            //lineObj.OnResize(LineOnResize);

            ////设置线的颜色
            //try
            //{
            //    lineObj.SetDrawingObjectParams("color", HideOutputlineColor.ToLower());
            //}
            //catch
            //{
            //    (FormDb.Db["Form1"] as Form1).textBox1.AppendText("该线条不支持此颜色以为你选择默认颜色!\r\n");
            //    lineObj.SetDrawingObjectParams("color", "red");
            //}

            ////永久保留该对象,不然会被垃圾回收机制回收
            //line = new HDrawingObjectEx
            //{
            //    HDrawingObject = lineObj,
            //    hTuples = lineTuple
            //};
            ////增加这个对象到指定Halcon窗口
            //hw.HalconWindow.AttachDrawingObjectToWindow(lineObj);
        }
        /// <summary>
        /// 更改高度宽度
        /// </summary>
        /// <param name="width"></param>
        /// <param name="heigth"></param>
        public void PushHeightWidth(double width, double heigth)
        {
            this.HideIntputWidth = width;
            this.HideIntputHeight = heigth;
        }
        /// <summary>
        /// 更改对比度平滑度
        /// </summary>
        /// <param name="width"></param>
        /// <param name="heigth"></param>
        public void PushThresholdSigma(double threshold, double sigma)
        {
            this.HideIntputThreshold = threshold;
            this.HideIntputSigma = sigma;
        }

        /// <summary>
        /// 更改颜色样式
        /// </summary>
        public void PushColor(string borderColor, string centerConlor, string lineColor)
        {
            this.HideOutputBorderColor = borderColor;
            this.HideOutputCenterConlor = centerConlor;
            this.HideOutputCenterConlor = lineColor;
        }
        /// <summary>
        /// 工具运行方法
        /// </summary>
        public void Run()
        {
            if (HideIntputImage == null)
            {
                throw new Exception("当前图像为空");
            }
            Bound_Line();
        }
        /// <summary>
        /// 工具的单次运行
        /// </summary>
        public void Tool_Run()
        {
            hw.HalconWindow.ClearWindow();
            HOperatorSet.DispObj(HideIntputImage, hw.HalconWindow);
            Run();
        }
    }
}
